//
//  PCXFile.m
//  MapEdit
//
//  Created by Steven Canfield on 30/06/07.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

#import "PCXFile.h"

void putColor( u_int8_t * dst, int dstIdx, int dstLength, u_int8_t *src, int srcIdx, int srcLength ) {
	int i;
	for( i = 0; i < 3; i++ ) {
		if( dstIdx >= dstLength ) {
			NSLog(@"Trying to index in dst past dstLength, %i vs %i ", dstIdx, dstLength );		
			abort();
		 }
		 if(  srcIdx >= srcLength ) {
			NSLog(@"Trying to index in src past srcLength, %i vs %i ", srcIdx, srcLength );		
			abort();
		}
		dst[ dstIdx ] = src[ srcIdx ];
		dstIdx++;
		srcIdx++;
	}
}

void printHeader( PCXHeader * header ) {
	printf("Manufacturer: %i\n", header->manufacturer );
	printf("Version: %i\n", header->version );
	printf("Encoding: %i\n", header->encoding );
	printf("BPP: %i\n", header->bpp );
	printf("Dimensions: (%i,%i) to (%i,%i)\n", header->min_x, header->min_y, header->max_x, header->max_y);
	
	int i = 0;
	printf("Color Table:\n");
	printf("map[#] = R,G,B\n");
	for( i = 0; i < 16; i++ ) {
		printf("map[%i] = %i,%i,%i\n", i, header->colormap[ i * 3 ], header->colormap[ i * 3 + 1], header->colormap[ i * 3 + 1] );
	}
}

void printPalette( u_int8_t * palette ) {
	int i = 0;
	printf("Color Table:\n");
	printf("map[#] = R,G,B\n");
	for( i = 0; i < 256; i++ ) {
		printf("map[%i] = %i,%i,%i\n", i, palette[ i * 3 ], palette[ i * 3 + 1], palette[ i * 3 + 2] );
	}
}

@implementation PCXFile
- (id)initWithData:(NSData *)data {
	self = [super init];
	if( self ) {
		int dataIndex = 0;
		[data getBytes:&header range:NSMakeRange( dataIndex, sizeof( PCXHeader ))];
		dataIndex += sizeof( PCXHeader );
				
		XSIZE = header.max_x - header.min_x + 1;
		YSIZE = header.max_y - header.min_y + 1;
		
		int dstSize = sizeof( u_int8_t ) * XSIZE * YSIZE * 3 ;
		bytes = malloc( dstSize );
		
		int BytesPerLine = header.planes * header.bpl;
		u_int8_t byte;
		int byteIndex = 0;
		
		int paletteSize = sizeof( u_int8_t ) * 256 * 3;
		palette = malloc( paletteSize );
				
		[data getBytes:palette range:NSMakeRange( [data length] - 768, 768 )];
				
		while( BytesPerLine > 0 && dataIndex < [data length] && byteIndex < dstSize ) {
			[data getBytes:&byte range:NSMakeRange( dataIndex, sizeof( u_int8_t ))];
			dataIndex += sizeof( u_int8_t );
			if( byte & 128 && byte & 64 ) {
				u_int8_t count = byte - 192;
				[data getBytes:&byte range:NSMakeRange( dataIndex, sizeof( u_int8_t ))];
				dataIndex += sizeof( u_int8_t );
				while( count-- && dataIndex < [data length]) {
					putColor( bytes, byteIndex, dstSize, palette, (byte * 3), paletteSize );
					byteIndex+=3;
				}
			} else {
				putColor( bytes, byteIndex, dstSize, palette, (byte * 3), paletteSize );
				byteIndex+=3;
			}
		}
	}

	return self;
}

- (NSColor *)colorAtX:(int)x Y:(int)y {
	return [NSColor colorWithNormalizedRed:bytes[3 *( y * XSIZE + x)] green:bytes[3 *( y * XSIZE + x) + 1]  blue:bytes[3 *( y * XSIZE + x) + 2]];
}

- (unsigned int*)pixelAtX:(int)x Y:(int)y {
	u_int8_t red = bytes[3 *( y * XSIZE + x)];
	u_int8_t green = bytes[3 *( y * XSIZE + x) + 1];
	u_int8_t blue = bytes[3 *( y * XSIZE + x) + 2];
	u_int8_t alpha = 255;
	
	unsigned int * storage = malloc( sizeof(int) * 4 );
	storage[0] = red;
	storage[1] = green;
	storage[2] = blue;
	storage[3] = alpha;
	return storage;
}

@end
